#include "gxhtc3.h"
#include "Delay.h"
#include "OLED.h"

float GXHTC3_temp, GXHTC3_humi, GXHTC3_Temperature, GXHTC3_Humidity;
static uint8_t CRC_8(uint8_t *Crc_ptr,uint8_t LEN)
{
	uint8_t CRC_Value = 0xFF;
	uint8_t i = 0,j = 0;
 
	for(i=0;i<LEN;i++)
	{
		CRC_Value ^= *(Crc_ptr+i);
		for(j=0;j<8;j++)
		{
			if(CRC_Value & 0x80)
				CRC_Value = (CRC_Value << 1) ^ 0x31;
			else
				CRC_Value = (CRC_Value << 1);
		}
	}
	return CRC_Value;
}
 
/*******************************************************************************
 * 函 数 名         : GXHTC3_read_result
 * 函数功能		   : GXHTC3 读6个字节数据
 *******************************************************************************/
void GXHTC3_read_result(u8 addr)
{
	u16 tem, hum;
	unsigned char buff[6];

	float Temperature = 0;
	float Humidity = 0;

	start();
	sendByte(addr << 1 | WRITE); // 写7位GXHTC3设备地址加0作为写取位,1为读取位
	waitAck();
	sendByte(0x78);
	waitAck();
	sendByte(0x66);
	waitAck();
	stop();

	Delay_ms(15); // 数据转换等待时间

	start();
	sendByte(addr << 1 | READ); // 写7位GXHTC3设备地址加0作为写取位,1为读取位

	if (waitAck() == 0)
	{
		sdaIn();
		buff[0] = recievedByte(1);
		buff[1] = recievedByte(1);
		buff[2] = recievedByte(1);
		buff[3] = recievedByte(1);
		buff[4] = recievedByte(1);
		buff[5] = recievedByte(0);
		stop();

		if (CRC_8(buff, 2) == buff[2] && CRC_8(buff + 3, 2) == buff[5])
		{
			tem = ((buff[0] << 8) | buff[1]); // 温度拼接
			hum = ((buff[3] << 8) | buff[4]); // 湿度拼接
			/*转换实际温度*/
			Temperature = (175.0 * (float)tem / 65535.0 - 45.0); // T = -45 + 175 * tem / (2^16-1)
			Humidity = (100.0 * (float)hum / 65535.0);			 // RH = hum*100 / (2^16-1)
		}
		else
		{
			GXHTC3_temp = 0;
			GXHTC3_humi = 0;
		}
	}

	if ((Temperature >= -20) && (Temperature <= 125) && (Humidity >= 0) && (Humidity <= 100)) // 过滤错误数据
	{
		GXHTC3_temp = Temperature;
		GXHTC3_humi = Humidity;
	}

	tem = 0;
	hum = 0;
}

/*******************************************************************************
 * 函 数 名         : al_float_buffer_sort
 * 函数功能		   : 多次读数值排序取中间值平均
 *******************************************************************************/
void al_float_buffer_sort(float *buf, uint8_t length)
{
	uint8_t i, j;
	float tmp;
	for (i = 0; i < length; i++)
	{
		for (j = i + 1; j < length; j++)
		{
			if (buf[j] < buf[i])
			{
				tmp = buf[j];
				buf[j] = buf[i];
				buf[i] = tmp;
			}
		}
	}
}

void al_get_gxth30_temp(void)
{
	float buff_temp[20], buff_humi[20];
	for (u8 i = 0; i < 10; i++)
	{
		GXHTC3_read_result(0x70);
		buff_temp[i] = GXHTC3_temp;
		buff_humi[i] = GXHTC3_humi;
	}

	al_float_buffer_sort(buff_temp, 10);
	al_float_buffer_sort(buff_humi, 10);

	GXHTC3_Temperature = (buff_temp[4] + buff_temp[5]) / 2;
	GXHTC3_Humidity = (buff_humi[4] + buff_humi[5]) / 2;

	debugprintf("temperature:%0.2f, humidity:%0.2f\r\n", GXHTC3_Temperature, GXHTC3_Humidity);
	int T;
	T = (int)GXHTC3_Temperature;
	int H;
	H = (int)GXHTC3_Humidity;
	OLED_ShowNum(1, 1, T, 2);
	OLED_ShowNum(2, 1, H, 2);
}
